package net.pulseproject.router.config;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;

import net.pulseproject.commons.misc.collection.Filter;
import net.pulseproject.commons.misc.collection.Matcher;
import net.pulseproject.router.modules.Module;

public class ModuleFilter extends Filter<Module> {
	
	@SuppressWarnings("unchecked")
	public final <T> Collection<T> filterByType(final Collection<Module> allModules, final Class<T> moduleType) {
		
		final Collection<Module> filteredModules = this.filter(allModules, new TypeMatcher(moduleType));
		final Collection<T> filteredTypedModules = new HashSet<T>();
		for (final Module module : filteredModules) {
			filteredTypedModules.add((T) module);
		}
		return filteredTypedModules;
	}

	public final Collection<Module> filterModulesById(final Collection<String> outgoingIds,
			final Map<String, Module> availableModules) {
		final Collection<Module> outgoingModules = new ArrayList<Module>(outgoingIds.size());
		
		for (final String id : outgoingIds) {
			final Module module = availableModules.get(id);
			if(module == null) {
				throw new RuntimeException("Could not find module with id [" + id + "]!");
			}
			outgoingModules.add(module);
		}
		
		return outgoingModules;
	}
	
	
	private static class TypeMatcher<T extends Module> implements Matcher<T> {
		
		private final Class<T> moduleType;
		
		public TypeMatcher(final Class<T> moduleType) {
			this.moduleType = moduleType;
		}

		@Override
		public final boolean matches(final Module instance) {
			return instance.getClass() == this.moduleType;
		}
	}
}
